/**
 * amount-control.js
 * amount control for increase and decrease of amount
 * =======================================================
 * Author: lute
 * Email: lutepluto@gmail.com
 */

(function(root, factory) {
  if(typeof module === 'object' && module.exports) {
    module.exports = function(root, Zepto) {
      if (Zepto === undefined) {
        if (typeof window !== 'undefined') {
          Zepto = require('zepto')
        } else {
          Zepto = require('zepto')(root)
        }
      }
      factory(Zepto)
      return Zepto
    }
  } else {
    factory(root.Zepto || root.jQuery || root.$)
  }
}(this, function($) {
  'use strict'

  var AmountControl = function(el, options) {
    this.$el       = $(el)
    this.$input    = this.$el.find('input[data-role]')
    this.$decrease = this.$el.find('[data-decrease]')
    this.$increase = this.$el.find('[data-increase]')
    this.options   = options
  }

  AmountControl.DEFAULTS = {
    minimum: 1,
    maximum: Infinity,
    onChange: null
  }

  AmountControl.prototype.checkInput = function() {
    // TODO handle directly input amount
  }

  AmountControl.prototype.change = function(difference) {
    if(difference === 0) return

    var old = this.$input.val() - 0
    if(difference > 0 && old < this.options.maximum) {
      this.$input.val(old + difference)
      this.$decrease.hasClass('disabled') && this.$decrease.removeClass('disabled')
      old + difference >= this.options.maximum && this.$increase.addClass('disabled')
    } else if(difference < 0 && old > this.options.minimum) {
      this.$input.val(old + difference)
      this.$increase.hasClass('disabled') && this.$increase.removeClass('disabled')
      old + difference <= this.options.minimum && this.$decrease.addClass('disabled')
    }

    this.$input.trigger('amountcontrol:change')

    this.options.onChange && this.options.onChange.call(this, this.$el, old + difference)
  }

  AmountControl.prototype.destroy = function() {
    $(document).off('tap.amountcontrol.increase', tapHandler)
    $(document).off('tap.amountcontrol.decrease', tapHandler)
  }

  function Plugin(option) {
    return this.each(function() {
      var $this = $(this)
      var data = $this.data('amount-control')
      var options = $.extend({}, AmountControl.DEFAULTS, $this.data(), typeof option === 'object' && option)

      if(!data) $this.data('amount-control', (data = new AmountControl(this, options)))
    })
  }

  var old = $.fn.amountControl

  $.fn.amountControl             = Plugin
  $.fn.amountControl.Constructor = AmountControl

  $.fn.amountControl.noConflict = function() {
    $.fn.amountControl = old
    return this
  }

  var tapHandler = function(e) {
    e.preventDefault()

    var $this = $(this)
    var $target = $($this.data('target'))
    var options = $.extend({}, AmountControl.DEFAULTS, $target.data(), $this.data())
    var difference = $this.data('increase') ? $this.data('increase') : 0 - $this.data('decrease')

    Plugin.call($target, options)

    if(difference) {
      $target.data('amount-control').change(difference)
    }
  }

  $(document)
    .on('click.amountcontrol.increase', '[data-increase]', tapHandler)
    .on('click.amountcontrol.decrease', '[data-decrease]', tapHandler)
  
}));
